home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
video
/
xevil-1.000
/
xevil-1
/
coord.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-10
|
7KB
|
458 lines
// "coord.C"
// TAG: CO
/* Copyright (C) 1994 Steve Hardt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Steve Hardt
hardts@athena.mit.edu hardts@media.mit.edu
hardts@r4002.3dem.bioch.bcm.tmc.edu
2043 McClendon
Houston, TX 77030
*/
#ifndef NO_PRAGMAS
#pragma implementation "coord.h"
#endif
// Include Files
#include "utils.h"
#include "coord.h"
// Functions.
void Stats::add_death(time_t birthTime)
{
time_t lifespan = time(NULL) - birthTime;
if (deaths > 0)
aveLifespan = (aveLifespan * deaths + lifespan) / (deaths + 1);
else
aveLifespan = lifespan;
deaths++;
}
int Pos::distance(const Pos &p) const
{
Size diff = *this - p;
assert (diff.abs_2() >= 0);
return (int)sqrt(diff.width * diff.width + diff.height * diff.height);
}
int Pos::distance_2(const Pos &p) const
{
Size diff = *this - p;
return diff.width * diff.width + diff.height * diff.height;
}
Dir Size::get_dir()
{
if (!width && !height)
return CO_air;
if (height < 0.5 * width)
if (height > -2 * width)
if (height < -0.5 * width)
return CO_UP_R;
else
return CO_R;
else
if (height < 2 * width)
return CO_UP;
else
return CO_UP_L;
else
if (height < -2 * width)
if (height < -0.5 * width)
return CO_L;
else
return CO_DN_L;
else
if (height < 2 * width)
return CO_DN_R;
else
return CO_DN;
}
void Size::get_dirs_4(Dir &d1,Dir &d2)
{
if (!width && !height)
{
d1 = d2 = CO_air;
return;
}
if (width)
d1 = (width > 0) ? CO_R : CO_L;
if (height)
d2 = (height > 0) ? CO_DN : CO_UP;
else
d2 = d1;
if (!width)
d1 = d2;
}
float Size::cross(const Vel &vel)
{
return width * vel.dy - height * vel.dx;
}
Boolean Box::overlap(const Loc &l)
{
if ((l.c >= loc.c) && (l.c < loc.c + dim.colMax) &&
(l.r >= loc.r) && (l.r < loc.r + dim.rowMax))
return True;
else
return False;
}
Vel Vel::shrink(float k) const
{
Vel ret = *this;
if (ret.dx > k)
ret.dx -= k;
else if (ret.dx < -k)
ret.dx += k;
else
ret.dx = 0;
if (ret.dy > k)
ret.dy -= k;
else if (ret.dy < -k)
ret.dy += k;
else
ret.dy = 0;
return ret;
}
void Vel::damp(float k)
{
if (dx > k)
dx -= k;
else if (dx < -k)
dx += k;
else
dx = 0;
if (dy > k)
dy -= k;
else if (dy < -k)
dy += k;
else
dy = 0;
}
Boolean Vel::is_zero() const
{
Boolean ret;
if ((dx == 0) && (dy == 0))
ret = True;
else
ret = False;
return ret;
}
Dir Vel::get_dir() const
{
if (!dx && !dy)
return CO_air;
if (dy < 0.5 * dx)
if (dy > -2 * dx)
if (dy < -0.5 * dx)
return CO_UP_R;
else
return CO_R;
else
if (dy < 2 * dx)
return CO_UP;
else
return CO_UP_L;
else
if (dy < -2 * dx)
if (dy < -0.5 * dx)
return CO_L;
else
return CO_DN_L;
else
if (dy < 2 * dx)
return CO_DN_R;
else
return CO_DN;
}
void Vel::limit(float k)
{
assert (k >= 0);
if (dx > k)
dx = k;
if (dx < -k)
dx = -k;
if (dy > k)
dy = k;
if (dy < -k)
dy = -k;
}
void Vel::get_dirs_4(Dir in[4],Dir out[4],int &inNum,int &outNum)
{
inNum = 0;
outNum = 0;
if (dx > 0)
{
in[inNum] = CO_R;
inNum++;
}
else
{
out[outNum] = CO_R;
outNum++;
}
if (dy > 0)
{
in[inNum] = CO_DN;
inNum++;
}
else
{
out[outNum] = CO_DN;
outNum++;
}
if (dx < 0)
{
in[inNum] = CO_L;
inNum++;
}
else
{
out[outNum] = CO_L;
outNum++;
}
if (dy < 0)
{
in[inNum] = CO_UP;
inNum++;
}
else
{
out[outNum] = CO_UP;
outNum++;
}
assert(inNum + outNum == 4);
}
Boolean operator == (const Loc &l1, const Loc &l2)
{
return l1.r == l2.r && l1.c == l2.c;
}
Boolean operator == (const Pos &p1, const Pos &p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
Boolean operator == (const Vel &v1, const Vel &v2)
{
return v1.dx == v2.dx && v1.dy == v2.dy;
}
Boolean operator == (const Size &s1, const Size &s2)
{
if ((s1.width == s2.width) && (s1.height == s2.height))
return True;
else
return False;
}
Boolean operator == (const GLoc &g1,const GLoc &g2)
{
return (g1.horiz == g2.horiz) && (g1.vert == g2.vert);
}
Boolean operator != (const GLoc &g1,const GLoc &g2)
{
return (g1.horiz != g2.horiz) || (g1.vert != g2.vert);
}
Pos operator + (const Pos &pos,const Size &size)
{
Pos ret;
ret.x = pos.x + size.width;
ret.y = pos.y + size.height;
return ret;
}
Pos operator - (const Pos &pos,const Size &size)
{
Pos ret;
ret.x = pos.x - size.width;
ret.y = pos.y - size.height;
return ret;
}
Size operator - (const Pos &p1,const Pos &p2)
{
Size ret;
ret.width = p1.x - p2.x;
ret.height = p1.y - p2.y;
return ret;
}
Pos operator + (const Pos &pos, const Vel &vel)
{
Pos ret;
/* We want it to round towards zero so that it does the same thing for
something going to the right as to the left. */
ret.x = pos.x + (int)vel.dx;
ret.y = pos.y + (int)vel.dy;
/* ret.x = pos.x + (int)trunc(vel.dx);
ret.y = pos.y + (int)trunc(vel.dy);
*/
return ret;
}
Size operator * (float k,const Size &size)
{
Size ret;
ret.width = (int)floor(k * size.width);
ret.height = (int)floor(k * size.height);
return ret;
}
Vel operator + (const Vel &v1,const Vel &v2)
{
Vel ret(v1.dx + v2.dx,v1.dy + v2.dy);
return ret;
}
Vel operator + (const Vel &vel, const Acc &acc)
{
Vel ret(vel.dx + acc.ddx,vel.dy + acc.ddy);
return ret;
}
Vel operator * (float k,const Vel &vel)
{
Vel ret(k * vel.dx, k * vel.dy);
return ret;
}
Vel operator / (float k,const Vel &vel)
{
Vel ret(k / vel.dx, k / vel.dy);
return ret;
}
Vel operator + (float k,const Vel &vel)
{
Vel ret(k + vel.dx,k + vel.dy);
return ret;
}
Acc operator * (int k,const Acc &acc)
{
Acc ret;
ret.ddx = k * acc.ddx;
ret.ddy = k * acc.ddy;
return ret;
}
Dir Coord::dir_opposite(Dir dir)
{
if (dir == CO_air)
return CO_air;
assert(dir >= CO_R && dir < CO_DIR_MAX);
return ((dir - CO_R + CO_DIR_PURE / 2) % CO_DIR_PURE) + CO_R;
}